#! /usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2020/10/4 22:57
# @Author : youngchaolin

''''''
'''
闭包
封闭的东西，保证数据的安全
内层函数对外层函数非全局变量的引用或使用
多用于面试题，可以忽略，反正我又不面试
'''

# 计算平均收盘价
li=[] # 收集价格的列表，使用全局变量

def make_average(new_value):
    li.append(new_value)
    return sum(li)/len(li)

print(make_average(100))
print(make_average(120))
# li有被修改的风险
# li.append(666)
print(make_average(110))
print(make_average(106))

# 但是上面使用全局变量的方法不安全，需要使用闭包解决
# 将收集价格的列表，定义在一个函数内，这样不会随便修改它
print('------分割线------')
def make_average1():
    # 定义在函数内
    l1=[]
    def average(new_value):
        l1.append(new_value)
        return sum(l1)/len(l1)
    return average

avg=make_average1()
print(avg)
print(avg(100))
print(avg(120))
print(avg(110))
print(avg(106))

# 闭包：内层函数对外层函数非全局变量的引用或使用，就会形成闭包
# 被引用的非全局变量也叫做自由变量，这个自由变量会和内层函数产生一个绑定关系
# 自由变量不会在内存中消失

# 闭包的作用：保证数据的安全

# 如何判断一个嵌套函数是不是闭包，就看内层函数有没有对外层函数变量的引用
# 闭包
def fun1():
    a=1
    def inner():
        print(a)
    return inner
ret=fun1()
print(ret)
print(ret())
print(ret.__code__.co_freevars)

# 闭包
def outer(a,b):
    def inner():
        print(a)
        print(b)
    return inner
ret=outer(3,4)
print(ret)
print(ret())

# 用代码判断闭包，看看函数有没有自由变量
print(ret.__code__.co_freevars) # ('a', 'b')

print(avg.__code__.co_freevars) # ('l1',)








